package ms.zuul.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.log4j.Logger;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StreamUtils;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;

/**
 * Project Name: ms
 * File Name: RequestAccessFilter
 * Package Name: ms.zuul.filter
 * Date: 2018/5/9  11:55
 * Copyright (c) 2018, tianyul All Rights Reserved.
 * 请求过滤器
 */
@Configuration
public class MsResponseFilter extends ZuulFilter {

    private Logger logger = Logger.getLogger(MsResponseFilter.class);

    @Override
    public String filterType() {
        //拦截请求方式
        return POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public boolean shouldFilter() {
        // statusCode == 200 的时候执行
        RequestContext ctx = RequestContext.getCurrentContext();
        int statusCode = ctx.getResponseStatusCode();
        return statusCode == HttpServletResponse.SC_OK && ctx.getResponseDataStream() != null;
    }

    @Override
    public Object run() {
        //获取请求上下文
        RequestContext ctx = RequestContext.getCurrentContext();

        //获取数据的流
        InputStream stream = ctx.getResponseDataStream();

        //转换成json
        String responseData;
        try {
            responseData = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));
        } catch (IOException e) {
            logger.error("getResponseDataStream fail!", e);
            throw new RuntimeException("getResponseDataStream fail!", e);
        }

        logger.info("request uri:{}, responseData:{}" + ctx.getRequest().getRequestURI() + responseData);
        //声明返回体
        MsResponseBody msResponseBody;
        try {
            //转成object
            Object jsonObj = JSON.parse(responseData);
            //根据类型，转换数据
            if (jsonObj instanceof JSONObject) {
                Map resultMap = ((JSONObject) jsonObj).toJavaObject(Map.class);
                msResponseBody = new MsResponseBody(ResponseCode.SUCCESS, resultMap);
            } else if (jsonObj instanceof JSONArray) {
                List<Map> resultList = ((JSONArray) jsonObj).toJavaList(Map.class);
                msResponseBody = new MsResponseBody(ResponseCode.SUCCESS, resultList);
            } else {
                // 其他类型直接作为字符串进行处理
                msResponseBody = new MsResponseBody(ResponseCode.SUCCESS, responseData);
            }
        } catch (JSONException jsonException) {
            // 如果 responseData 是一个非数字类型的字符串，且不符合json格式，则直接当字符串进行处理
            msResponseBody = new MsResponseBody(ResponseCode.SUCCESS, responseData);
        }

        //返回数据
        ctx.setResponseBody(JSON.toJSONString(msResponseBody));

        return null;
    }

}
